package com.szl.sbssh.utils;

import java.util.Arrays;
import java.util.Date;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

//import org.quartz.impl.triggers.CronTriggerImpl;

/**
 * 字符串工具類
 * 
 * @author songzhonglin
 *
 */
public class StringUtil {

	/**
	 * 格式化字符串
	 * 
	 * 例：formateString("xxx{0}bbb",1) = xxx1bbb
	 * 
	 * @param str
	 * @param params
	 * @return
	 */
	public static String formateString(String str, String... params) {
		for (int i = 0; i < params.length; i++) {
			str = str.replace("{" + i + "}", params[i] == null ? "" : params[i]);
		}
		return str;
	}

	/**
	 * 字符串時候為空
	 * 
	 * @param v
	 * @return
	 */
	public static boolean isEmpty(String v) {
		if (v == null || v.length() <= 0) {
			return true;
		}
		return false;
	}

	/**
	 * 字符串時候為空
	 * 
	 * @param v
	 * @return
	 */
	public static boolean isEmpty(Object obj) {
		if (obj == null) {
			return true;
		}
		return false;
	}

	/**
	 * 字符串時候為空
	 * 
	 * @param v
	 * @return
	 */
	public static boolean isNotEmpty(Object obj) {
		if (obj == null) {
			return false;
		}
		return true;
	}

	/**
	 * 字符串時候為空
	 * 
	 * @param v
	 * @return
	 */
	public static boolean isNotEmpty(String v) {
		if (v == null || v.length() <= 0) {
			return false;
		}
		return true;
	}

	/**
	 * 将String型转换为Int型
	 * 
	 * @param intstr
	 * @return
	 */
	public static int stringTolnt(String intstr) {
		Integer integer;
		integer = Integer.valueOf(intstr);
		return integer.intValue();
	}

	/**
	 * 将Int型转换为String型
	 * 
	 * @param value
	 * @return
	 */
	public static String intToString(int value) {
		Integer integer = new Integer(value);
		return integer.toString();
	}

	/**
	 * 将String型转换为float型
	 * 
	 * @param floatstr
	 * @return
	 */
	public static float stringToFloat(String floatstr) {
		Float floatee;
		floatee = Float.valueOf(floatstr);
		return floatee.floatValue();
	}

	/**
	 * 将float型转换为String型
	 * 
	 * @param value
	 * @return
	 */
	public static String floatToString(float value) {
		Float floatee = new Float(value);
		return floatee.toString();
	}

	/**
	 * 将String型转换为sqlDate型
	 * 
	 * @param dateStr
	 * @return
	 */
	public static java.sql.Date stringToDate(String dateStr) {
		return java.sql.Date.valueOf(dateStr);
	}

	/**
	 * 将sqlDate型转换为String型
	 * 
	 * @param datee
	 * @return
	 */
	public static String dateToString(java.sql.Date datee) {
		return datee.toString();
	}

	/**
	 * 
	 * @param value
	 *            当前值
	 * @param len
	 *            不满足长度
	 * @return
	 */
	public static String getZeroToLeft(int value, String len) {
		if (isNotEmpty(intToString(value)) && isNotEmpty(len)) {
			String format = "%0" + len + "d";
			System.out.println(format);
			String str = String.format(format, value);
			return str;
		}
		return null;

	}

	/**
	 * 利用正则表达式判断字符串是否是数字
	 * 
	 * @param str
	 * @return
	 */
	public static boolean isNumeric(String str) {
		Pattern pattern = Pattern.compile("[0-9]*");
		Matcher isNum = pattern.matcher(str);
		if (!isNum.matches()) {
			return false;
		}
		return true;
	}

	/**
	 * HTML字符转义
	 * 
	 * @see 对输入参数中的敏感字符进行过滤替换,防止用户利用JavaScript等方式输入恶意代码
	 * @see String input = <img src='http://t1.baidu.com/it/fm=0&gp=0.jpg'/>
	 * @see HtmlUtils.htmlEscape(input); //from spring.jar
	 * @see StringEscapeUtils.escapeHtml(input); //from commons-lang.jar
	 * @see 尽管Spring和Apache都提供了字符转义的方法,但Apache的StringEscapeUtils功能要更强大一些
	 * @see StringEscapeUtils提供了对HTML,Java,JavaScript,SQL,XML等字符的转义和反转义
	 * @see 但二者在转义HTML字符时,都不会对单引号和空格进行转义,而本方法则提供了对它们的转义
	 * @return String 过滤后的字符串
	 */
	public static String htmlEscape(String input) {
		if (isEmpty(input)) {
			return input;
		}
		input = input.replaceAll("&", "&amp;");
		input = input.replaceAll("<", "&lt;");
		input = input.replaceAll(">", "&gt;");
		input = input.replaceAll(" ", "&nbsp;");
		input = input.replaceAll("'", "&#39;"); // IE暂不支持单引号的实体名称,而支持单引号的实体编号,故单引号转义成实体编号,其它字符转义成实体名称
		input = input.replaceAll("\"", "&quot;"); // 双引号也需要转义，所以加一个斜线对其进行转义
		input = input.replaceAll("\n", "<br/>"); // 不能把\n的过滤放在前面，因为还要对<和>过滤，这样就会导致<br/>失效了
		return input;
	}

	/**
	 * 获取系统流水号
	 * 
	 * @param length
	 *            指定流水号长度
	 * @param toNumber
	 *            指定流水号是否全由数字组成
	 */
	public static String getSysJournalNo(int length, boolean isNumber) {
		// replaceAll()之后返回的是一个由十六进制形式组成的且长度为32的字符串
		String uuid = UUID.randomUUID().toString().replaceAll("-", "");
		if (uuid.length() > length) {
			uuid = uuid.substring(0, length);
		} else if (uuid.length() < length) {
			for (int i = 0; i < length - uuid.length(); i++) {
				uuid = uuid + Math.round(Math.random() * 9);
			}
		}
		if (isNumber) {
			return uuid.replaceAll("a", "1").replaceAll("b", "2").replaceAll("c", "3").replaceAll("d", "4")
					.replaceAll("e", "5").replaceAll("f", "6");
		} else {
			return uuid;
		}
	}

	/**
	 * 金额元转分
	 * 
	 * @see 注意:该方法可处理贰仟万以内的金额,且若有小数位,则不限小数位的长度
	 * @see 注意:如果你的金额达到了贰仟万以上,则不推荐使用该方法,否则计算出来的结果会令人大吃一惊
	 * @param amount
	 *            金额的元进制字符串
	 * @return String 金额的分进制字符串
	 */
	public static String moneyYuanToFen(String amount) {
		if (isEmpty(amount)) {
			return amount;
		}
		// 传入的金额字符串代表的是一个整数
		if (-1 == amount.indexOf(".")) {
			return Integer.parseInt(amount) * 100 + "";
		}
		// 传入的金额字符串里面含小数点-->取小数点前面的字符串,并将之转换成单位为分的整数表示
		int money_fen = Integer.parseInt(amount.substring(0, amount.indexOf("."))) * 100;
		// 取到小数点后面的字符串
		String pointBehind = (amount.substring(amount.indexOf(".") + 1));
		// amount=12.3
		if (pointBehind.length() == 1) {
			return money_fen + Integer.parseInt(pointBehind) * 10 + "";
		}
		// 小数点后面的第一位字符串的整数表示
		int pointString_1 = Integer.parseInt(pointBehind.substring(0, 1));
		// 小数点后面的第二位字符串的整数表示
		int pointString_2 = Integer.parseInt(pointBehind.substring(1, 2));
		// amount==12.03,amount=12.00,amount=12.30
		if (pointString_1 == 0) {
			return money_fen + pointString_2 + "";
		} else {
			return money_fen + pointString_1 * 10 + pointString_2 + "";
		}
	}

	/**
	 * 金额元转分
	 * 
	 * @see 该方法会将金额中小数点后面的数值,四舍五入后只保留两位....如12.345-->12.35
	 * @see 注意:该方法可处理贰仟万以内的金额
	 * @see 注意:如果你的金额达到了贰仟万以上,则非常不建议使用该方法,否则计算出来的结果会令人大吃一惊
	 * @param amount
	 *            金额的元进制字符串
	 * @return String 金额的分进制字符串
	 */
	public static String moneyYuanToFenByRound(String amount) {
		if (isEmpty(amount)) {
			return amount;
		}
		if (-1 == amount.indexOf(".")) {
			return Integer.parseInt(amount) * 100 + "";
		}
		int money_fen = Integer.parseInt(amount.substring(0, amount.indexOf("."))) * 100;
		String pointBehind = (amount.substring(amount.indexOf(".") + 1));
		if (pointBehind.length() == 1) {
			return money_fen + Integer.parseInt(pointBehind) * 10 + "";
		}
		int pointString_1 = Integer.parseInt(pointBehind.substring(0, 1));
		int pointString_2 = Integer.parseInt(pointBehind.substring(1, 2));
		// 下面这种方式用于处理pointBehind=245,286,295,298,995,998等需要四舍五入的情况
		if (pointBehind.length() > 2) {
			int pointString_3 = Integer.parseInt(pointBehind.substring(2, 3));
			if (pointString_3 >= 5) {
				if (pointString_2 == 9) {
					if (pointString_1 == 9) {
						money_fen = money_fen + 100;
						pointString_1 = 0;
						pointString_2 = 0;
					} else {
						pointString_1 = pointString_1 + 1;
						pointString_2 = 0;
					}
				} else {
					pointString_2 = pointString_2 + 1;
				}
			}
		}
		if (pointString_1 == 0) {
			return money_fen + pointString_2 + "";
		} else {
			return money_fen + pointString_1 * 10 + pointString_2 + "";
		}
	}

	/**
	 * 金额分转元
	 * 
	 * @see 注意:如果传入的参数中含小数点,则直接原样返回
	 * @see 该方法返回的金额字符串格式为<code>00.00</code>,其整数位有且至少有一个,小数位有且长度固定为2
	 * @param amount
	 *            金额的分进制字符串
	 * @return String 金额的元进制字符串
	 */
	public static String moneyFenToYuan(String amount) {
		if (isEmpty(amount)) {
			return amount;
		}
		if (amount.indexOf(".") > -1) {
			return amount;
		}
		if (amount.length() == 1) {
			return "0.0" + amount;
		} else if (amount.length() == 2) {
			return "0." + amount;
		} else {
			return amount.substring(0, amount.length() - 2) + "." + amount.substring(amount.length() - 2);
		}
	}

	/**
	 * 判断输入的字节数组是否为空
	 * 
	 * @return boolean 空则返回true,非空则flase
	 */
	public static boolean isEmpty(byte[] bytes) {
		return null == bytes || 0 == bytes.length;
	}

	/**
	 * 字符串右补空格
	 * 
	 * @see 该方法默认采用空格(其ASCII码为32)来右补字符
	 * @see 若想自己指定所补字符,可以使用
	 *      <code>rightPadForByte(String str, int size, int padStrByASCII)</code>
	 *      方法
	 */
	public static String rightPadForByte(String str, int size) {
		return rightPadForByte(str, size, 32);
	}

	/**
	 * 字符串右补字符
	 * 
	 * @see 若str对应的byte[]长度不小于size,则按照size截取str对应的byte[],而非原样返回str
	 * @see 所以size参数很关键..事实上之所以这么处理,是由于支付处理系统接口文档规定了字段的最大长度
	 * @see 若对普通字符串进行右补字符,建议org.apache.commons.lang.StringUtils.rightPad(...)
	 * @param size
	 *            该参数指的不是字符串长度,而是字符串所对应的byte[]长度
	 * @param padStrByASCII
	 *            该值为所补字符的ASCII码,如32表示空格,48表示0,64表示@等
	 */
	public static String rightPadForByte(String str, int size, int padStrByASCII) {
		byte[] srcByte = str.getBytes();
		byte[] destByte = null;
		if (srcByte.length >= size) {
			// 由于size不大于原数组长度,故该方法此时会按照size自动截取,它会在数组右侧填充'(byte)0'以使其具有指定的长度
			destByte = Arrays.copyOf(srcByte, size);
		} else {
			destByte = Arrays.copyOf(srcByte, size);
			Arrays.fill(destByte, srcByte.length, size, (byte) padStrByASCII);
		}
		return new String(destByte);
	}

	/**
	 * 字符串左补空格
	 * 
	 * @see 该方法默认采用空格(其ASCII码为32)来左补字符
	 * @see 若想自己指定所补字符,可以使用
	 *      <code>leftPadForByte(String str, int size, int padStrByASCII)</code>
	 *      方法
	 */
	public static String leftPadForByte(String str, int size) {
		return leftPadForByte(str, size, 32);
	}

	/**
	 * 字符串左补字符
	 * 
	 * @see 若str对应的byte[]长度不小于size,则按照size截取str对应的byte[],而非原样返回str
	 * @see 所以size参数很关键..事实上之所以这么处理,是由于支付处理系统接口文档规定了字段的最大长度
	 * @param padStrByASCII
	 *            该值为所补字符的ASCII码,如32表示空格,48表示0,64表示@等
	 */
	public static String leftPadForByte(String str, int size, int padStrByASCII) {
		byte[] srcByte = str.getBytes();
		byte[] destByte = new byte[size];
		Arrays.fill(destByte, (byte) padStrByASCII);
		if (srcByte.length >= size) {
			System.arraycopy(srcByte, 0, destByte, 0, size);
		} else {
			System.arraycopy(srcByte, 0, destByte, size - srcByte.length, srcByte.length);
		}
		return new String(destByte);
	}

//	public static boolean isValidExpression(final String cronExpression) {
//		CronTriggerImpl trigger = new CronTriggerImpl();
//		try {
//			trigger.setCronExpression(cronExpression);
//			Date date = trigger.computeFirstFireTime(null);
//			return date != null;
//		} catch (Exception e) {
//			e.printStackTrace();
//		}
//		return false;
//	}
	
	public static String warpper(String str, String warpper){
		String result = "";
		if(isNotEmpty(str) && isNotEmpty(warpper)){
			result = warpper+str+warpper;
		}
		return result;
	}

	public static void main(String[] args) {
		int n = 1;
		// String str = String.format("%05d", n);
		// System.out.println(str);
		// String zero=getZeroToLeft(123,"4");
		// System.out.println(zero);
//
//		Singleton singleton = new Singleton();
//
//		singleton.add("11.5", "12.75");
//		isValidExpression("dddd");
	}

}
